package com.lognsoft.shell;

import java.io.File;
import java.lang.Process;
import java.lang.String;
import java.util.Hashtable;
import java.io.OutputStream;


public class ShellExecute 
{
	public int _exit_code = 0;
	public int _count_in_millsecond =0;	
	public int _timeout = -1;
	
	private static Hashtable<String,String>  _CommandAlias = 
		new Hashtable<String,String>();

	private static Hashtable<String,Integer> _ShellCommand = 
		new Hashtable<String,Integer>();

	private final static String[] _WindowsCommand = 
	{
		"dir",		"cd",		"pushd",	"popd",
		"del",		"rd",		"md",		"copy",
		"prompt",	"set",		"path",		"call"		
	};
	
	private final static String[] _BashCommand = 
	{
		"ls",		"pushd",	"popd",		"cd",
		""
	};
	
public static void init()
{
	String[] commands = File.separatorChar == '\\' 
				? _WindowsCommand 
				: _BashCommand;
	
	for (String i : commands)
	{
		_ShellCommand.put(i, 0);
	}
}
public static String getAlias(String cmd)
{
	String v = _CommandAlias.get(cmd);
	return v == null ? cmd : v;
}

public static String replaceAlias(String command)
{
	command = command.trim();
	int ind = command.indexOf(' ');
	
	String cmd = ind > 0 ? command.substring(0, ind) : command;
	String cmdAction = _CommandAlias.get(cmd);
	
	if (cmdAction == null)
	{
		return command;
	}

	if (ind < 0)
	{
		return cmdAction;
	}
	else
	{
		return cmdAction + command.substring(ind, command.length());
	}
}

public static void setAlias(String key,String command)
{
	_CommandAlias.put(key, replaceAlias (command) );
}

/* command [1>stdout] [2>err]
 * shell [1>stdout] [2>err] 
 * internal command
 * command1 && command2 &&
 * command1 | command2
 * 
 * 
 * */
private static Process createProcess(String current_path, String s)
{
	/* if at Windows */
	if (File.separatorChar == '\\') 
	{
		s = "cmd /c prompt $G$S && " + s;
	}

	try
	{
		Process p = Runtime.getRuntime().exec(s, null, new File(current_path));	
		return p;
	}
	catch (Exception e)
	{
		return null;
	}
};

public String run_stringOut (String current_path, String s, boolean stderr)
{
	Process p = createProcess(current_path, s);
	
	if (p == null)
	{
		return "";
	}
	
	AsyncStreamReader err,out;
	
	err = new AsyncStreamReader (p.getErrorStream());
	out = new AsyncStreamReader (p.getInputStream());
	
	if (stderr)
	{
		err.setStreamOut( System.err, false);
	}
	
	out.setStringOut();
	
	run_internal(p, err, out);
	
	return out.getAsString();
}

private boolean run_internal (Process p, AsyncStreamReader err, AsyncStreamReader out)
{
	try
	{
		err.start();
		out.start();
	
		_exit_code = p.waitFor();
		
		err.waitResult(_timeout);
		out.waitResult(_timeout);	
		
		return true;
	}
	catch (Exception e)
	{
		return false;
	}
}

public boolean run_stdout (String current_path, String s, boolean stderr)
{
	Process p = createProcess(current_path, s);
	
	if (p == null)
	{
		return false;
	}
	
	AsyncStreamReader err,out;
	
	err = new AsyncStreamReader (p.getErrorStream());
	out = new AsyncStreamReader (p.getInputStream());
	
	if (stderr)
	{
		err.setStreamOut( System.err, false);
	}
	
	out.setStreamOut( System.out, false );
	
	return run_internal(p, err, out);
}

public boolean run_fileOut (
	String current_path, 
	String s, 
	OutputStream errOS,
	OutputStream stdOS)
{
	Process p = createProcess(current_path, s);
	
	if (p == null)
	{
		return false;
	}
	
	AsyncStreamReader err,out;
	
	err = new AsyncStreamReader (p.getErrorStream());
	out = new AsyncStreamReader (p.getInputStream());
	
	err.setStreamOut(errOS, false);
	out.setStreamOut(stdOS, false);
	
	return run_internal(p, err, out);
}

}
